﻿using System;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using UnityEngine;

namespace FpFrame
{
    [CreateAssetMenu(fileName = "DIContainerSO", menuName = "DI/DIContainerSO")]
    public partial class DIContainerSO : ScriptableObject
    {
        [SerializeField]
        private ScriptableObject[] serviceManagers;

        private readonly Dictionary<Type, object> _instances = new();

        // 自动注册可拖拽的非 Mono 服务（SO）
        public void RegisterScriptableServices()
        {
            foreach (var so in serviceManagers)
            {
                if (so is IService service)
                {
                    RegisterInstance(service.GetType(), service);
                    if (service is ServiceManagerSo sms)
                        sms.InjectResolver(this);
                }
                else
                {
                    Debug.LogWarning($"{so.name} is not a service (missing IService)");
                }
            }
        }

        // 自动注册所有场景中的 MonoManager
        public void AutoRegisterMonoManagers()
        {
            var managers = GameObject.FindObjectsOfType<MonoManager>(true);
            foreach (var m in managers)
            {
                RegisterInstance(m.GetType(), m);
                m.InjectResolver(this);
            }
        }

        public void RegisterInstance<T>(T instance) => RegisterInstance(typeof(T), instance);

        private void RegisterInstance(Type type, object instance) => _instances[type] = instance;

        public T Resolve<T>() => (T)_instances[typeof(T)];

        public IEnumerable<object> GetAllRegistered() => _instances.Values;

        // --------------------------
        // 按层统一管理初始化/启动/释放
        // --------------------------
        public async UniTask InitAllAsync()
        {
            // 核心层先初始化
            foreach (var core in _instances.Values.OfType<CoreManager>())
                await core.InitAsync();

            foreach (var core in _instances.Values.OfType<CoreManager>())
                await core.StartAsync();

            // 模块层再初始化
            foreach (var module in _instances.Values.OfType<ModuleManager>())
                await module.InitAsync();

            foreach (var module in _instances.Values.OfType<ModuleManager>())
                await module.StartAsync();
        }

        public void DisposeAll()
        {
            // 模块层先释放
            foreach (var module in _instances.Values.OfType<ModuleManager>())
                module.Dispose();

            // 核心层再释放
            foreach (var core in _instances.Values.OfType<CoreManager>())
                core.Dispose();
        }
    }
}
